﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

using MonoDevelop.Ide;
using MonoDevelop.Core;
using MonoDevelop.Projects.Dom;
using MonoDevelop.Projects.Dom.Parser;

using Coq.MonoDevelop;

using Ast;
using CoqAuWin;
using Microsoft.FSharp.Text.Lexing;


namespace Coq.MonoDevelop
{
    public class CoqParsedDocument : ParsedDocument
    {
        public CoqAST Ast { get; private set; }

        public CoqParsedDocument(string fileName, string content):base(fileName) 
        {
            Ast = Main.ParseCSHARP(content);
        }
    }

    public class CoqParser : AbstractParser
    {
        public CoqParsedDocument document { get; private set; }


        public CoqParser() : base("Coq", "text/x-coq") 
        {
            CoqProcessAgent.Service.NotifyParsingFinished += new Microsoft.FSharp.Control.FSharpHandler<EventArgs>(Service_NotifyParsingFinished);
        }

        void Service_NotifyParsingFinished(object sender, EventArgs arg)
        {
            if (document == null)
                return;
            document.Errors.Clear();
            if (arg as ErrorResultEventArgs == null)
                return;

            var args = arg as ErrorResultEventArgs;
            if (args.ContainsError)
                document.Errors.Add(new Error(ErrorType.Error, new DomRegion(args.StartLine, args.StartPos, args.EndLine, args.EndPos), args.Message));
            
        }

        public override bool CanParse(string fileName)
        {
            //Move somewhere else
            return (Common.SupportedExtension(Path.GetExtension(fileName)));
        }

        private void SimpleParse(string content)
        {
            //Cut the code into statements
            if (CoqProcessAgent.Service.UpdatingErrors)
                return;
            SimpleCoqAST spast = null;
            try
            {
                spast = Coq.MonoDevelop.SimpleParser.SimpleParse(content);
            }
            catch
            {
                Debug.WriteLine("simpleparser fail");
            }

            //sends the code to be processed by the coqprocess and saves the reactions for each line until the first error (which is returned)
            if (spast != null)
            {
                CoqProcessAgent.Service.ProcessMessage(spast.Item);
            }

            return;
        }

        public override ParsedDocument Parse(ProjectDom dom, string fileName, string content)
        {
            Debug.WriteLine("Parsing in mono");
            document = new CoqParsedDocument(fileName, content);

            SimpleParse(content);

            return document;
        }
    }
}
